package com.progenies.ecg.asm31.model.codeparts.lines;

import com.progenies.ecg.model.ValueReference;
import com.progenies.ecg.model.codeparts.ICodePart;
import com.progenies.ecg.model.codeparts.lines.IVariableFactory;
import com.progenies.ecg.model.codeparts.lines.LineCodePart;

public class VariablesFactoryASM31 implements IVariableFactory {

	/* (non-Javadoc)
	 * @see com.progenies.ecg.model.codeparts.lines.asm31_impl.ILineFactory#createLocalVariable(java.lang.String, java.lang.Class)
	 */
	@Override
	public <T> LineCodePart createLocalVariable(String name, Class<T> type)
	{
		return new CreateLocalVariableLineCodePart<T>(name, type);
	}
	
	/* (non-Javadoc)
	 * @see com.progenies.ecg.model.codeparts.lines.asm31_impl.ILineFactory#createLocalVariable(java.lang.String, java.lang.Class, boolean)
	 */
	@Override
	public <T> LineCodePart createLocalVariableAndInitialize(String name, Class<T> type)
	{
		CreateLocalVariableLineCodePart<T> result=new CreateLocalVariableLineCodePart<T>(name, type);
		result.setInitialize(true);
		return result;
	}
	
	@Override
	public <T> LineCodePart createLocalArrayVariable(String name, Class<T> type, ValueReference<?>[] variableReferences) {
		return new CreateLocalVariableLineCodePart<T>(name, type, variableReferences);
	}
	
	@Override
	public <T> LineCodePart createLocalArrayVariable(String name, Class<T> type, ValueReference<?>[][] variableReferences) {
		return new CreateLocalVariableLineCodePart<T>(name, type, variableReferences);
	}



	@Override
	public <T> LineCodePart createLocalArrayVariable(String name, Class<T> type, int arraySize)
	{
		return new CreateLocalVariableLineCodePart<T>(name, type, new int[] {arraySize}, true);
	}
	
	@Override
	public <T> LineCodePart createLocalArrayVariable(String name, Class<T> type, int arraySize[])
	{
		return new CreateLocalVariableLineCodePart<T>(name, type, arraySize, true);
	}

	
	/* (non-Javadoc)
	 * @see com.progenies.ecg.model.codeparts.lines.asm31_impl.ILineFactory#createLocalVariable(java.lang.String, java.lang.Class, T)
	 */
	@Override
	public <T> LineCodePart createLocalVariable(String name, Class<T> type, T value)
	{
		return new CreateLocalVariableLineCodePart<T>(name, type, value);
	}
	
	@Override
	public <T> LineCodePart createLocalVariableFromVariable(String name, Class<T> type, String referencedVariablename)
	{
		return new CreateLocalVariableLineCodePart<T>(name, type, ValueReference.forVariable(referencedVariablename));
	}
	
	
	
	
	

	@Override
	public <T> LineCodePart createEmptyArrayAndStore(Class<T> type, int[] arrayDimensions, String name) {
		return new CreateArrayLinePart<T>(type, name, arrayDimensions);
	}
	
	
	@Override
	public <T> LineCodePart createArrayAndStore(Class<T> type, T value,	String name)
	{
		return new CreateArrayLinePart<T>(type, value, name);
	}
	
	@Override
	public <T> LineCodePart createArrayAndStore(Class<T> type, String name, ValueReference<?>[] variableReferences)
	{
		return new CreateArrayLinePart<T>(type, name, variableReferences);
	}
	

	@Override
	public <T> LineCodePart createArrayAndStore(Class<T> type, String name, ValueReference<?>[][] variableReferences)
	{
		return new CreateArrayLinePart<T>(type, name, variableReferences);
	}

	
	
	/* (non-Javadoc)
	 * @see com.progenies.ecg.model.codeparts.lines.asm31_impl.ILineFactory#setVariableValue(java.lang.String, T)
	 */
	@Override
	public <T> LineCodePart setVariableValue(String name, T value)
	{
		SetVariableValueLinePart<T> varLinePart=new SetVariableValueLinePart<T>(name);
		varLinePart.setValue(value);
		return varLinePart;
		
	}
	


	@Override
	public LineCodePart setVariableValueFromVariable(String name, String originName)
	{
		SetVariableValueLinePart<Object> varLinePart=new SetVariableValueLinePart<Object>(name);
		varLinePart.setOriginValueVariable(originName);
		return varLinePart;

	}

	@Override
	public ICodePart setVariableValueFromObjectField(String name, String objectVariableName, String fieldName, Class<?> fieldType) {
		SetVariableValueLinePart<Object> varLinePart=new SetVariableValueLinePart<Object>(name);
		varLinePart.setOriginValueVariable(objectVariableName);
		varLinePart.setFieldInsideOrigin(fieldName);
		varLinePart.setFieldInsideOriginType(fieldType);
		return varLinePart;
	}

	@Override
	public ICodePart setVariableValueFromStaticClassField(String name, Class<?> ownerClass, String staticFieldName, Class<?> fieldType) {
		SetVariableValueLinePart<Object> varLinePart=new SetVariableValueLinePart<Object>(name);
		varLinePart.setOriginOwnerClass(ownerClass);
		varLinePart.setFieldInsideOrigin(staticFieldName);
		varLinePart.setFieldInsideOriginType(fieldType);
		return varLinePart;
	}

	@Override
	public ICodePart setVariableValueNull(String variableName) {
		SetVariableValueLinePart<Object> varLinePart=new SetVariableValueLinePart<Object>(variableName);
		varLinePart.setValue(SetVariableValueLinePart.FORZED_NULL);
		return varLinePart;
	}

	@Override
	public LineCodePart incrementVariable(String name) {
		return new IncrementVariable(name, 1);
	}

	@Override
	public LineCodePart incrementVariable(String name, int ammount)	{
		return new IncrementVariable(name, ammount);
	}

	@Override
	public LineCodePart decrementVariable(String name) {
		return incrementVariable(name, -1);
	}

	@Override
	public <T> LineCodePart setStaticFieldValue(String name,	Class<?> ownerClass, T value)
	{
		SetVariableValueLinePart<T> varLinePart=new SetVariableValueLinePart<T>(name);
		varLinePart.setTargetOwnerClass(ownerClass);
		varLinePart.setValue(value);
		return varLinePart;
	}

	@Override
	public <T> LineCodePart setFieldInFieldValue(String name, String fieldOwner, T value) {
		SetVariableValueLinePart<T> varLinePart=new SetVariableValueLinePart<T>(name);
		varLinePart.setTargetOwnerVariable(fieldOwner);
		varLinePart.setValue(value);
		return varLinePart;
	}





}
